package steampunk.art;

import java.awt.Graphics2D;
import java.util.Hashtable;

import steampunk.geom.RectGeom;

/**
 * The point of this class is to be able to show more than one sequence of frames. This
 * could be nice if you want to, say, have the character be able to play different
 * animations when walking as opposed to jumping or dying.
 * @author g
 *
 */
public class DynamicSprite extends RectGeom implements Art {

	private Hashtable<String, Sprite> spriteTable = new Hashtable<String, Sprite>();
	private final Object spriteLock = new Object();
	private Sprite current = null;
	private Sprite defsprite = null;
	
	public DynamicSprite() {
		super(1, 1);
	}

	@Override
	public void draw(Graphics2D g) {
		synchronized (spriteLock) {
		if (current != null) {
			double x = getX();
			double y = getY();
			g.translate(x, y);
			current.draw(g);
			g.translate(-x, -y);
		}
		}
	}

	@Override
	public void updateArt(double seconds) {
		synchronized (spriteLock) {
		if (current != null) {
			current.updateArt(seconds);
			setWidth(current.getWidth());
			setHeight(current.getHeight());
		}
		}
	}
	
	/**
	 * Sets what Sprite will be used if setSprite(String) is called
	 * and can't find a sprite with the given name.
	 * @param sprite
	 */
	public void setDefaultSprite(Sprite sprite) {
		synchronized (spriteLock) {
			this.defsprite = sprite;
			if (current == null) {
				setSprite(defsprite);
			}
		}
	}
	
	/**
	 * Changes the animation to the Sprite with the 
	 * given name (see putSprite(String, Sprite))
	 * @param key
	 */
	public void setSprite(String key) {
		synchronized (spriteLock) {
			if (spriteTable.containsKey(key)) {
				Sprite s = spriteTable.get(key);
				setSprite(s);
			} else {
				if (defsprite != null) {
					setSprite(defsprite);
				}
			}
			updateArt(0); // update graphics
		}
	}

	/**
	 * Changes the animations to given Sprite
	 * @param sprite
	 */
	public void setSprite(Sprite sprite) {
		synchronized (spriteLock) {
			if (this.current == sprite) {
				return; // not necessary
			}
			sprite.reset();
			this.current = sprite;
		}
	}
	
	/**
	 * Stores the (name, sprite) pair so that you can use it
	 * later with the setSprite(String) method
	 * @param name
	 * @param sprite
	 */
	public void putSprite(String name, Sprite sprite) {
		synchronized (spriteLock) {
			spriteTable.put(name, sprite);
		}
	}
}
